package com.dnkj.download.task.core.excel;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.example.webdownloadserver.core.excel.ExcelExportVO;
import com.example.webdownloadserver.core.excel.ExtExcel;
import com.example.webdownloadserver.util.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import cn.afterturn.easypoi.excel.annotation.Excel;

/**
 * 
 * <p>
 * 导出核心处理类
 * </p>
 * @title ShuabaoExcelExportHandler.java
 * @package com.dnkj.download.task.core.excel 
 * @author ying.xiao
 * @version 0.1 2020年12月5日
 */
public class ExcelExportHandler {

	static Logger LOGGER = LoggerFactory.getLogger(ExcelExportHandler.class);
	
	List<ExcelExportVO> voList = null;
	
	private static String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss", YYYYMMDD = "yyyy-MM-dd",YYYMM = "yyyy-MM";
	
	public ExcelExportHandler(Class<?> pojoClass) {
		voList = getExcelExportVOList(pojoClass);
	}
	
	/**获取导出实体注解信息*/
	@SuppressWarnings("unchecked")
	public List<ExcelExportVO> getExcelExportVOList(Class<?> pojoClass){
		List<ExcelExportVO> voList =  new ArrayList<ExcelExportVO>();
		Field[] fields = getClassFields(pojoClass);
		for (Field field : fields) {
			Excel excel = field.getAnnotation(Excel.class);
			if (excel == null) {
				continue;
			}
			ExcelExportVO vo = new ExcelExportVO();
			vo.setColumn(field.getName());
			if ((field.getType().getSimpleName().contains(int.class.getSimpleName()) 
					|| field.getType().getSimpleName().contains(Integer.class.getSimpleName()))) {
				vo.setColumType(Integer.class.getSimpleName());
			} else if (field.getType().getSimpleName().contains(String.class.getSimpleName()) ) {
				vo.setColumType(String.class.getSimpleName());
			} else if ((field.getType().getSimpleName().contains(long.class.getSimpleName()) 
					|| field.getType().getSimpleName().contains(Long.class.getSimpleName())) ) {
				vo.setColumType(Long.class.getSimpleName());
			} else if (field.getType().getSimpleName().contains(Double.class.getSimpleName()) ) {
				vo.setColumType(Double.class.getSimpleName());
			} else if (field.getType().getSimpleName().contains(Date.class.getSimpleName())) {
				vo.setColumType(Date.class.getSimpleName());
			} else if (field.getType().getSimpleName().contains(BigDecimal.class.getSimpleName())) {
				vo.setColumType(BigDecimal.class.getSimpleName());
			}
			vo.setName(excel.name());
			vo.setFormat(excel.format());
			ExtExcel extExcel = field.getAnnotation(ExtExcel.class);
//			Desensitized desensitized = field.getAnnotation(Desensitized.class);
			if (extExcel != null) {
				vo.setDictType(extExcel.dictType());
				vo.setNumberConvert(extExcel.numberConvert());
				vo.setExtSuffix(extExcel.extSuffix());
				String mapJson = extExcel.mapJson();
				if(StringUtils.isNotEmpty(mapJson)) {
					try {
						Map<String,String> dictMap = JsonUtils.parser(mapJson, Map.class);
						vo.setDictMap(dictMap);
					}catch(Exception e) {
						LOGGER.error("parse dictMap error",e);
					}
				}
			}
//			if (desensitized != null) {
//				vo.setType(desensitized.type());
//			}
			voList.add(vo);
		}
		return voList;
	}
	
	/**创建workbook*/
	public SXSSFWorkbook getWorkbook() {
		return new SXSSFWorkbook(1000);
	}
	
	/**创建sheet*/
	public void createSheet(SXSSFWorkbook wb,String sheetName) {
		wb.createSheet(sheetName);
	}
	
	/**创建表头*/
	public void createExcel(SXSSFWorkbook wb,String sheetName) {
		Sheet sheet = wb.getSheet(sheetName);
		CellStyle style = wb.createCellStyle();
		style.setVerticalAlignment(VerticalAlignment.CENTER);
		style.setAlignment(HorizontalAlignment.CENTER);
		style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
		style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		style.setBorderBottom(BorderStyle.THIN);
		style.setBorderLeft(BorderStyle.THIN);
		style.setBorderRight(BorderStyle.THIN);
		style.setBorderTop(BorderStyle.THIN);
		style.setAlignment(HorizontalAlignment.CENTER);
		Font font = wb.createFont();
		font.setColor(HSSFColor.VIOLET.index);
		font.setFontHeightInPoints((short) 12);
		font.setBold(true);
		style.setFont(font);
		sheet.setDefaultColumnWidth(15);
		Row row = sheet.createRow((short) 0);
		for(int i=0;i<voList.size();i++) {
			Cell cell = row.createCell(i);
			cell.setCellValue(voList.get(i).getName());
			cell.setCellStyle(style);
		}
	}
	
	/**填充数据*/
	public void writeExcel(Collection<?> dataSet,SXSSFWorkbook wb,int j, String sheetName)throws Exception {
		Sheet sheet = wb.getSheet(sheetName);
		Row row = null;
		Cell cell = null;
		CellStyle style2 = wb.createCellStyle();
		style2.setVerticalAlignment(VerticalAlignment.CENTER);
		style2.setAlignment(HorizontalAlignment.CENTER);
		// style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
		// style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style2.setBorderBottom(BorderStyle.THIN);
		style2.setBorderLeft(BorderStyle.THIN);
		style2.setBorderRight(BorderStyle.THIN);
		style2.setBorderTop(BorderStyle.THIN);
		// style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		Font font2 = wb.createFont();
		font2.setBold(true);
		style2.setFont(font2);
		Iterator<?> its = dataSet.iterator();
		int i = 0;
		while (its.hasNext()) {
			Object t = its.next();
			row = sheet.createRow(i + j);
			for(int k=0;k<voList.size();k++) {
				ExcelExportVO vo = voList.get(k);
				cell = row.createCell(k);
				Object val = getFieldVal(vo.getColumn(), t);
				if(vo.getNumberConvert() != 0) {
					String temp = getConvertNumVal(vo, val);
					cell.setCellValue(temp);
				}
//				if(vo.getType() != null) {
//					String temp = SensitiveInfoUtils.convertMsg(vo.getType(), val.toString());
//					cell.setCellValue(temp);
//				}
				if(vo.getDictMap() != null && !vo.getDictMap().isEmpty()) {
					try {
						String temp = (val!=null?vo.getDictMap().get(val.toString()):"");
						cell.setCellValue(temp);
					}catch(Exception e) {
						LOGGER.error("getDictMap error",e);
						cell.setCellValue(val!=null?val.toString():"");
					}
				}else {
					if(StringUtils.isEmpty(vo.getDictType()) &&
							(vo.getNumberConvert() == 0 || vo.getNumberConvert() == 1) 
//							&& vo.getType() == null
							) {
						String temp = getTempObjVal(vo, val);
						if(StringUtils.isNotEmpty(vo.getExtSuffix())) {
							temp += vo.getExtSuffix();
						}	
						cell.setCellValue(temp);
					}
				}
				cell.setCellStyle(style2);
			}
			i++;
		}
	}
	
	/**获取对象所有属性*/
    public Field[] getClassFields(Class<?> pojoClass) {
        List<Field> list = new ArrayList<Field>();
        Field[] fields;
        do {
            fields = pojoClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                list.add(fields[i]);
            }
            pojoClass = pojoClass.getSuperclass();
        } while (pojoClass != Object.class && pojoClass != null);
        return list.toArray(fields);
    }
    
    /**获取对象指定属性值*/
    public Object getFieldVal(String column,Object pojo)throws Exception {
    	PropertyDescriptor pd = new PropertyDescriptor(column, pojo.getClass());
		Method m = pd.getReadMethod();
		Object val = m.invoke(pojo);
		return val;
    }
    
    /**获取转化单位值*/
    private String getConvertNumVal(ExcelExportVO vo,Object val) {
    	if(val == null) {
    		if(BigDecimal.class.getSimpleName().equals(vo.getColumType())) {
    			return "0.0";
    		}
    		return "";
    	}
    	double number = 0L;
		if (Integer.class.getSimpleName().equals(vo.getColumType())) {
			number = ((Integer) val).doubleValue();
		}
		if (Long.class.getSimpleName().equals(vo.getColumType())) {
			number = ((Long) val).doubleValue();
		}
		if (Double.class.getSimpleName().equals(vo.getColumType())) {
			number = ((Double) val).doubleValue();
		}
		String temp = new BigDecimal(number).divide(new BigDecimal(vo.getNumberConvert())).toPlainString();
		return temp;
    }

    /**转化属性值*/
    private String getTempObjVal(ExcelExportVO vo,Object val) {
    	String temp = "";
    	if(val == null) {
    		if(BigDecimal.class.getSimpleName().equals(vo.getColumType())) {
    			return "0.0";
    		}
    		return temp;
    	}
    	if (Integer.class.getSimpleName().equals(vo.getColumType())) {
			temp = String.valueOf((Integer) val);
		}
		if (String.class.getSimpleName().equals(vo.getColumType())) {
			temp = val.toString();
		}
		if (Long.class.getSimpleName().equals(vo.getColumType())) {
			temp = String.valueOf((Long) val);
		}
		if (Double.class.getSimpleName().equals(vo.getColumType())) {
			temp = String.valueOf((Double) val);
		}
		if(BigDecimal.class.getSimpleName().equals(vo.getColumType())) {
			temp = String.valueOf((BigDecimal) val);
		}
		if(Boolean.class.getSimpleName().equals(vo.getColumType())) {
			temp = String.valueOf(val);
		}
		if (Date.class.getSimpleName().equals(vo.getColumType())) {
			String format = checkFormat(vo.getFormat());
			SimpleDateFormat sdf = new SimpleDateFormat(format);
	        temp = sdf.format(val);
		}
		return temp;
    }
    
    /**检查时间格式*/
    private String checkFormat(String pattern) {
    	if(StringUtils.isEmpty(pattern) || (!YYYYMMDDHHMMSS.equals(pattern) 
    			&& !YYYYMMDD.equals(pattern) && !YYYMM.equals(pattern))) {
			return YYYYMMDDHHMMSS;
		}
    	return pattern;
    }
    
}

